Veery testing

code=yes

todo:
 - logout
 - delete a post
 - undelete a post
 - show list of deleted posts
 - conduct tag search

(add to couchdb the ability to generate a list of tag names and their counts, if possible. two display options would be nice: by tag name and count. like with Grebe and Junco. need the couchdb equivalent to count(*) and group_by in SQL.)



Read a Single Post
==================

Grab my profile page. Currently, the default is to return HTML only.
  curl http://veeryapiperl.soupmode.com/api/posts/profile

This produces the same thing.
  curl http://veeryapiperl.soupmode.com/api/posts/profile/?text=html

{
  "status":200,
  "description":"OK",
  "post": 
    {
      "author":"MrX",
      "reading_time":0,
      "created_at":"2015/02/11 14:54:49",
      "updated_at":"2015/04/21 15:56:10",
      "slug":"profile",
      "post_type":"article",
      "title":"Profile",
      "word_count":16,
      "html":"<a name=\"Profile\"></a>\n<h1 class=\"headingtext\"><a href=\"/profile\">Profile</a></h1>\n\n<p>my profile page that contains nothing because i want to blend into the background.</p>\n\n<p><img src=\"http://farm4.static.flickr.com/3156/2614312687_3fe4cae2a9_o.jpg\" alt=\"\" /></p>\n"
    }
}


Get the markup. The _rev is returned for updating. Should this be returned, however, only if the client calling app is logged in?
  curl http://veeryapiperl.soupmode.com/api/posts/profile/?text=markup

{
  "status":200,
  "description":"OK",
  "post":
    {
      "_rev":"3-97b3bc9434ea346a49b7709c6dd1e9fd",
      "title":"Profile",
      "slug":"profile",
      "post_type":"article",
      "markup":"# Profile\r\n\r\nmy profile page that contains nothing because i want to blend into the background.\r\n\r\n![](http://farm4.static.flickr.com/3156/2614312687_3fe4cae2a9_o.jpg)"
    }
}



Get the markup and the HTML.
  curl http://veeryapiperl.soupmode.com/api/posts/profile/?text=full

{
  "status":200,
  "description":"OK",
  "post":
    {
      "author":"MrX",
      "title":"Profile",
      "slug":"profile",
      "post_type":"article",
      "word_count":16,
      "reading_time":0,
      "created_at":"2015/02/11 14:54:49",
      "updated_at":"2015/04/21 15:56:10",
      "markup":"# Profile\r\n\r\nmy profile page that contains nothing because i want to blend into the background.\r\n\r\n![](http://farm4.static.flickr.com/3156/2614312687_3fe4cae2a9_o.jpg)",
      "html":"<a name=\"Profile\"></a>\n<h1 class=\"headingtext\"><a href=\"/profile\">Profile</a></h1>\n\n<p>my profile page that contains nothing because i want to blend into the background.</p>\n\n<p><img src=\"http://farm4.static.flickr.com/3156/2614312687_3fe4cae2a9_o.jpg\" alt=\"\" /></p>\n"
    }
}



Get the Homepage Stream of Posts
================================

curl http://veeryapiperl.soupmode.com/api/posts

Page 3 of the stream of posts
curl http://veeryapiperl.soupmode.com/api/posts/?page=3


{
"status":200,
"description":"OK",
"posts":
  [
    {
      "author":"MrX",
      "reading_time":0,
      "more_text_exists":1,
      "tags":[],
      "text_intro":" <span class=\"streamtitle\"><a href=\"/test-multimarkdown\">test multimarkdown</a></span> -   Here is as example of [table][simple_table] followed by a more complex example from the documentation   simple_table       \tFirst Header \tSecond Header \tThird Header \t      \tFirst row \tData \tVery long data entry \t    \tSecond row \tCell \tCell \t       Prototype table       ...",
      "updated_at":"2015/04/30 01:57:55",
      "formatted_updated_at":"Apr 30, 2015 01:57:55 Z",
      "slug":"test-multimarkdown",
      "post_type":"article"
    },
    {
      "author":"MrX",
      "reading_time":0,
      "more_text_exists":0,
      "tags":["scaup","blogging"],
      "text_intro":"<span class=\"streamtitle\"><a href=\"/info\">Info</a></span> -   Minimal web publishing tool.  Formatting can be created by using markup syntax from Markdown, MultiMarkdown, Textile, and HTML.  Tech used:   Ubuntu Nginx FastCGI Perl HTML::Template CouchDB Memcached Elasticsearch  <a href=\"/tag/scaup\">#scaup</a> <a href=\"/tag/blogging\">#blogging</a>",
      "updated_at":"2015/04/29 21:56:57",
      "formatted_updated_at":"Apr 29, 2015 21:56:57 Z",
      "slug":"info",
      "post_type":"article"
    }
  ]
}





Stream of posts from a search request
=====================================

 ** Currently, searches are done with GET requests. Should add or change this to POST requests?

Search on "beer"
curl http://veeryapiperl.soupmode.com/api/searches/string/beer

Search on "craft beer"
curl http://veeryapiperl.soupmode.com/api/searches/string/craft%20beer


 ** Elasticsearch notes: it seems that when entering a text string surrounded by double quotes, then an exact string match is conducted by Elasticsearch. When a plus sign separates words, then it seems than an OR Boolean search is conducted.


 ** will eventually support tag search
    curl http://veeryapiperl.soupmode.com/api/searches/tag/beer

    OR

    curl http://veeryapiperl.soupmode.com/api/tags/beer


Returned JSON for search on "beer" :

{
    "status":200,
    "description":"OK",
    "next_link_bool":0,
    "posts":[
        {
            "author":"MrX",
            "reading_time":1,
            "text_intro":" <span class=\"streamtitle\"><a href=\"/black-cloister-feb-26-2015-notes\">Black Cloister Feb 26 2015 notes</a></span> -   Feb 26, 2015 - Toledo Blade - Black Cloister Brewing Co. taps opening date  The story is part of a new Blade column, called \"Raise a Glass.\"  ",
            "slug":"black-cloister-feb-26-2015-notes",
            "formatted_updated_at":"Feb 26, 2015 16:14:32 Z",
            "post_type":"article",
            "more_text_exists":1,
            "tags":["toledo","beer","brewery"],
            "updated_at":"2015/02/26 16:14:32"
        },
        {
            "author":"MrX",
            "reading_time":1,
            "text_intro":"<span class=\"streamtitle\"><a href=\"/jan-15-2015-insights-from-tom-at-titgemeiers\">Jan 15, 2015 insights from Tom at Titgemeier's.</a></span> -   I visited Titgemeier's this morning to buy bird seed, honey, and a bottle capper. I broke our capper last night.  I chatted with Tom for a while. We definitely missed a good Glass City Mashers meeting last Thursday. Chris spoke. He's the owne ...",
            "slug":"jan-15-2015-insights-from-tom-at-titgemeiers",
            "formatted_updated_at":"Feb 25, 2015 13:27:01 Z",
            "post_type":"article",
            "more_text_exists":1,
            "tags":["beer","business","toledo"],
            "updated_at":"2015/02/25 13:27:01"
        }

    ]    
}






Login - creating and sending the no password login link
=======================================================

curl -X POST -H "Content-Type: application/json" --data '{ "email" : "x@x.com"}' http://veeryapiperl.soupmode.com/api/users/login


{    
    "status":200,
    "session_id_rev":"1-073335f570d5cf202bac424e0b05cb9b",
    "system_message":"A new login link has been created and sent.",
    "user_message":"Creating New Login Link",
    "description":"OK"
}

The 'session_id_rev' name=value is only included in the returned JSON when 'debug_mode' equals '1' in the YAML config file.


Login - activating the no password login link
=============================================

This will create the user's login session.

curl http://veeryapiperl.soupmode.com/api/users/login/?rev=12345

Returned JSON:

{
    "author_name":"MrX",
    "session_id":"50ff8f05c0f5d95aabbe7c5d810323c8",
    "status":200,
    "description":"OK"
}

'author_name' and 'session_id' are returned if 'debug_mode' equals '1' in the YAML config file.




Create a New Post
=================

curl -X POST -H "Content-Type: application/json" --data '{"author": "MrX", "session_id": "5012344558568686", "submit_type": "Post", "markup": "h1. 13may2015 2059\n\n test post from Perl Veery API"}' http://veeryapiperl.soupmode.com/api/posts


Returned JSON

{
    "html":"<a name=\"13may2015_2059\"></a>\n<h1 class=\"headingtext\"><a href=\"/13may2015-2059\">13may2015 2059</a></h1>\n\n<p> test post from Perl Veery <span class=\"caps\">API</span></p>",
    "status":200,
    "rev":"1-f6eaf40f56dbb2ccc07919535f891ee1",
    "post_id":"13may2015-2059",
    "description":"OK"
}




Update a Post
=============

Preview 
-------

curl -X PUT -H "Content-Type: application/json" --data '{"author": "MrX", "session_id": "50ff8f05c0f5d95aabbe7c5d810323c8", "rev": "50ff8f05c0f5d95aabbe7c5d810323c8", "post_id": "13may2015-2059", "submit_type": "Preview", "markup": "h1. 13may2015 2059\n\n Updated - test post from Perl Veery API"}' http://veeryapiperl.soupmode.com/api/posts


{
    "html":"<a name=\"13may2015_2059\"></a>\n<h1 class=\"headingtext\"><a href=\"/\">13may2015 2059</a></h1>\n\n<p> Updated - test post from Perl Veery <span class=\"caps\">API</span></p>",
    "status":200,
    "description":"OK"
}


Wrong Rev info Submitted on Update
----------------------------------

{
    "status":"400",
    "system_message":"Invalid rev information provided.",
    "user_message":"Unable to update post.",
    "description":"Bad Request"
}


Not logged in when trying to create or update content
-----------------------------------------------------

{
    "status":"400",
    "system_message":"You are not logged in.",
    "user_message":"Unable to peform action.",
    "description":"Bad Request"
}



Successfully updating a post
----------------------------

curl -X PUT -H "Content-Type: application/json" --data '{"author": "MrX", "session_id": "50ff8f05c0f5d95aabbe7c5d810323c8", "rev": "1-f6eaf40f56dbb2ccc07919535f891ee1", "post_id": "13may2015-2059", "submit_type": "Update", "markup": "h1. 13may2015 2059\n\n Updated - test post from Perl Veery API"}' http://veeryapiperl.soupmode.com/api/posts

Returned JSON:

{
    "html":"<a name=\"13may2015_2059\"></a>\n<h1 class=\"headingtext\"><a href=\"/13may2015-2059\">13may2015 2059</a></h1>\n\n<p> Updated - test post from Perl Veery <span class=\"caps\">API</span></p>",
    "status":200,
    "rev":"2-43eb2b79a7d58de0e3678387cfd1e5c9",
    "description":"OK"
}





======================================
======================================


Three "doc" types. If this was SQL, these would be three separate tables.

Author

(I think '_id' now contains the same value as 'name')

{
"_id" : "50ff8f05c0f5d95aabbe7c5d810006f8",
"_rev" : "1-435be1729c60657a333adee6e190869d",
"type" : "author",
"name" : "MrX",
"email" : "mrx@mrx.com",
"current_session_id" : "50ff8f05c0f5d95aabbe7c5d81026436"
}


Session ID Description

{
"_id" : "50ff8f05c0f5d95aabbe7c5d81026c1a",
"_rev" : "2-91027f061be5f73ccb9784d1fff8210e",
"type" : "session_id",
"created_at" : "2015/04/17 18:53:03",
"updated_at" : "2015/04/17 18:53:03",
"status" : "active"
}


Post (Article or Note) Description

{
"_id" : "test-post",
"_rev" : "4-ad0c0316a32ac4b217431127130fd516",
"author" : "MrX",
"reading_time" : 2,
"text_intro" : "paragraph of text",
"created_at" : "2015/04/17 13:37:35",
"html" : "entire post formatted in HTML",
"post_type" : "article",
"markup" : "entire markup of the post",
"more_text_exists" : 1,
"tags" : ["scaup","blogging","couchdb"],
"post_status" : "public",
"updated_at" : "2015/04/17 14:09:30",
"word_count" : 432,
"type" : "post",
"title" : "Test post"
}